package com.mt.roll.core.utils;

import com.alibaba.fastjson.JSON;
import com.mt.roll.core.exception.ApiException;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import static java.util.stream.Collectors.toList;

/**
 * Bean 工具类
 */
public class BeanUtils {
    /**
     * 使用{@link org.springframework.beans.BeanUtils#copyProperties(Object, Object, String...)}拷贝
     *
     * @param list             源对象列表
     * @param targetClass      目标对象类型
     * @param ignoreProperties 忽略字段
     * @param <T>              源对象
     * @param <R>              目标对象
     * @return 目标对象列表
     */
    public static <T, R> List<R> copyList(List<T> list, Class<R> targetClass, String... ignoreProperties) {
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        return list.stream().map((t) -> {
            try {
                R r;
                //如果包含builder方法则为使用lombok.Builder注解的类，该注解只在编译期间有效，编译后的class中无法获取该注解
                try {
                    Method builder = targetClass.getDeclaredMethod("builder");
                    Object invoke = builder.invoke(null, null);
                    r = (R) invoke.getClass().getDeclaredMethod("build").invoke(invoke);
                } catch (NoSuchMethodException e) {
                    r = targetClass.newInstance();
                }
                org.springframework.beans.BeanUtils.copyProperties(t, r, ignoreProperties);
                return r;
            } catch (Exception e) {
                e.printStackTrace();
                throw new ApiException("对象拷贝异常");
            }
        }).collect(toList());
    }

    /**
     * 使用{@link JSON#parseArray(String, Class)}拷贝
     *
     * @param list        源对象列表
     * @param targetClass 目标对象类型
     * @param <T>         源对象
     * @param <R>         目标对象
     * @return 目标对象列表
     */
    public static <T, R> List<R> copyListWithJson(List<T> list, Class<R> targetClass) {
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        return JSON.parseArray(JSON.toJSONString(list), targetClass);
    }

}
